import asyncio
import concurrent.futures
from queue import Queue

from flask import Response, stream_with_context, copy_current_request_context

from owl_ai.application.graph_service import GraphInvokeDTO, GraphInvokeService
from owl_common.descriptor.serializer import JsonSerializer
from owl_common.descriptor.validator import BodyValidator
from ... import reg


@reg.api.route('/graph/streaming', methods=['POST'])
@JsonSerializer()
@BodyValidator()
def streaming(dto: GraphInvokeDTO):
    with reg.app.app_context():
        chunks_stream = GraphInvokeService.stream(dto, reg.app)
        response_stream = GraphInvokeService.streaming(chunks_stream)

        #events = GraphInvokeService.stream(dto)
        #ret = GraphInvokeService.streaming_events(events)

        return Response(response_stream, mimetype='text/event-stream')


async def async_generator():
    for i in range(5):
        await asyncio.sleep(1)
        yield f"data: {i + 1}\n\n"


def sync_generator():
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    q = Queue()

    async def task():
        async for item in async_generator():
            q.put(item)
            print(f"put item: {item}")
        q.put(None)  # 用 None 标识结束

    with concurrent.futures.ThreadPoolExecutor() as executor:
        executor.submit(loop.run_until_complete, task())

        print("while循环开始")
        while True:
            item = q.get()
            print(item)
            if item is None:
                break
            yield item


@reg.app.route('/test/stream')
def async_stream():
    return Response(stream_with_context(sync_generator()), mimetype='text/event-stream')
